/**
 * 
 */
package org.statewalker.parser.turtle.tokenizer;

import org.statewalker.parser.turtle.TurtleDict1;
import org.statewalker.parser.turtle.tokenizer.UriRefTokenizer.UriRefToken;
import org.statewalker.tokenizer.CharStream;
import org.statewalker.tokenizer.ITokenizer;
import org.statewalker.tokenizer.StreamToken;
import org.statewalker.tokenizer.CharStream.Marker;
import org.statewalker.tokenizer.CharStream.Pointer;
import org.statewalker.tokenizer.base.SequenceTokenizer;
import org.statewalker.tokenizer.base.SpaceTokenizer;

/**
 * <pre>
 * [4]  prefixID    ::= '@prefix' ws+ prefixName? ':' uriref
 * </pre>
 * 
 * @author kotelnikov
 */
public class BaseTokenizer implements ITokenizer {

    public static class BaseToken extends StreamToken {

        private UriRefToken fUriToken;

        public BaseToken(
            String key,
            boolean open,
            boolean close,
            Pointer begin,
            Pointer end,
            String str) {
            super(key, open, close, begin, end, str);
        }

        public BaseToken(String key, CharStream stream, Marker marker) {
            super(key, stream, marker);
        }

        public BaseToken(String key, Pointer begin, Pointer end, String str) {
            super(key, begin, end, str);
        }

        public UriRefToken getUriToken() {
            return fUriToken;
        }

        public void setUriToken(UriRefToken uriToken) {
            fUriToken = uriToken;
        }

    }

    public final static BaseTokenizer INSTANCE = new BaseTokenizer();

    private SequenceTokenizer fBaseTokenizer;

    private String fKey;

    private UriRefTokenizer fUriTokenizer;

    public BaseTokenizer() {
        this(TurtleDict1._BASE, UriRefTokenizer.INSTANCE);
    }

    /**
     * 
     */
    public BaseTokenizer(String key, UriRefTokenizer uriTokenizer) {
        fBaseTokenizer = new SequenceTokenizer(key, "@base");
        fUriTokenizer = uriTokenizer;
        fKey = key;
    }

    public StreamToken read(CharStream stream) {
        Marker marker = stream.markPosition();
        BaseToken result = null;
        try {
            if (fBaseTokenizer.read(stream) == null) {
                return null;
            }
            SpaceTokenizer.INSTANCE.read(stream);
            UriRefToken uriToken = (UriRefToken) fUriTokenizer.read(stream);
            if (uriToken == null)
                return null;
            result = new BaseToken(fKey, stream, marker);
            result.setUriToken(uriToken);
            return result;
        } finally {
            marker.close(result == null);
        }
    }

}
